package pl.edu.pw.elka.dzielins.revanalyzer.instance;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import pl.edu.pw.elka.dzielins.revanalyzer.model.ModelObject;
import pl.edu.pw.elka.dzielins.revanalyzer.model.ModelRelation;

public class InstanceRelation {
	private String name;
	private List<InstanceObject> arguments;
	private ModelRelation baseRelation;
	private InstanceObject owner;
	
	public InstanceRelation(InstanceObject owner, String name, ModelRelation baseRelation, InstanceObject... elements) {
		if (StringUtils.isBlank(name))
			throw new IllegalArgumentException("\"" + name
					+ "\" is not valid relation name");
		/*if (elements == null || elements.length == 0)
			throw new IllegalArgumentException(
					"Relation has to have at least one element");*/
		this.name = name;
		this.owner = owner;
		this.baseRelation = baseRelation;
		this.arguments = new LinkedList<InstanceObject>();
		for (int i = 0; i < baseRelation.getArguments().size(); ++i) {
			if (elements != null)
				this.arguments.add(elements[i]);
			else
				this.arguments.add(null);
		}
	}

	// getters & setters
	
	public String getName() {
		return name;
	}

	public InstanceObject getOwner() {
		return owner;
	}

	public void setOwner(InstanceObject owner) {
		this.owner = owner;
	}

	public ModelRelation getBaseRelation() {
		return baseRelation;
	}

	public void setBaseRelation(ModelRelation baseRelation) {
		this.baseRelation = baseRelation;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<InstanceObject> getArguments() {
		return arguments;
	}

	public void setArgument(List<InstanceObject> arguments) {
		this.arguments = arguments;
	}

	// other methods
	
	public List<String> getArgumentNames() {
		List<String> list = new ArrayList<String>(getBaseRelation().getArguments().size());
		for (InstanceObject argument : getArguments())
			list.add(argument.getName());
		return list;
	}
	
	public boolean referencesObject(InstanceObject object) {
		return (arguments.contains(object) || owner == object);
	}
	
	public List<InstanceObject> getArgumentsWithOwner() {
		List<InstanceObject> result = new ArrayList<InstanceObject>(1+arguments.size());
		result.add(owner);
		result.addAll(arguments);
		return result;
	}

	@Override
	public String toString() {
		String s = getName() + " : ";
		for (int i = 0; i < arguments.size() - 1; ++i) {
			if (arguments.get(i) != null) {
				s += arguments.get(i).getName() + " -> ";
			} else {
				s += "    -> "; 
			}
		}
		if (arguments.get(arguments.size() - 1) != null) {
			s += arguments.get(arguments.size() - 1).getName();
		} else {
			s += "   ";
		}
		return s;
	}
}
